package com.sunlands.qdcy.tongzhuo.service;


import com.sunlands.qdcy.tongzhuo.model.DiaryTopicDO;
import com.sunlands.qdcy.tongzhuo.model.UserDiaryTopicAttentionDO;
import com.sunlands.qdcy.tongzhuo.model.UserDiaryTopicHistoryDO;
import com.sunlands.qdcy.tongzhuo.repository.DiaryTopicRepository;
import com.sunlands.qdcy.tongzhuo.repository.UserDiaryTopicAttentionRepository;
import com.sunlands.qdcy.tongzhuo.repository.UserDiaryTopicHistoryRepository;
import com.sunlands.qdcy.tongzhuo.util.BeanPropertiesUtil;
import com.sunlands.qdcy.tongzhuo.vo.HistoryTopicVO;
import com.sunlands.qdcy.tongzhuo.vo.MyTopicVO;
import com.sunlands.qdcy.tongzhuo.vo.Page;
import com.sunlands.qdcy.tongzhuo.vo.RecommendTopicVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.sunlands.qdcy.tongzhuo.config.RedisConfig.CacheKeys.*;

/**
 * @author shixiaopeng
 */
@Slf4j
@Service
public class UserDiaryTopicService implements BeanPropertiesUtil {

    @Autowired
    DiaryTopicRepository diaryTopicRepository;
    @Autowired
    UserDiaryTopicHistoryRepository userDiaryTopicHistoryRepository;
    @Autowired
    UserDiaryTopicAttentionRepository userDiaryTopicAttentionRepository;
    @Autowired
    DiaryService diaryService;

    @Cacheable(cacheNames = TOPIC_RECOMMEND, key = "#key", unless = "#result == null")
    public List<RecommendTopicVO> recommendTopic(String key) {
        List<DiaryTopicDO> all = diaryTopicRepository.findAllByUserIdOrderByUpdateTimeDesc(0L);

        List<RecommendTopicVO> recommendTopicVOList = new ArrayList<>();
        for (DiaryTopicDO diaryRecommendTopic : all) {
            RecommendTopicVO recommendTopicVO = new RecommendTopicVO();
            copyNonNullProperties(diaryRecommendTopic, recommendTopicVO);
            recommendTopicVOList.add(recommendTopicVO);
        }
        return recommendTopicVOList;
    }

    @CacheEvict(cacheNames = TOPIC_RECOMMEND, key = "#key", condition = "#topicId != null")
    public void modifyTopicHot(String key, Long topicId) {
        DiaryTopicDO diaryTopic = diaryTopicRepository.findOne(topicId);
        //系统推荐的话题，才可以设置热门
        if (diaryTopic.getUserId() == 0L && !diaryTopic.getIsHot()) {
            Long count = diaryService.countByTopicId(topicId);
            if (count >= 10) {
                diaryTopic.setIsHot(true);
                diaryTopicRepository.save(diaryTopic);
            }
        }
    }

    @Cacheable(cacheNames = TOPIC_HISTORY, key = "#userId", unless = "#result == null")
    public List<String> historyTopic(String userId) {
        List<UserDiaryTopicHistoryDO> userDiaryTopicHistoryList = userDiaryTopicHistoryRepository.findByUserIdAndIsDeleteOrderByUpdateTimeDesc(Long.parseLong(userId), false);
        if (userDiaryTopicHistoryList.size() > 0) {
            return userDiaryTopicHistoryList.stream().map(UserDiaryTopicHistoryDO::getTopic).collect(Collectors.toList());
        } else {
            return Collections.emptyList();
        }
    }

    @CacheEvict(cacheNames = TOPIC_HISTORY, key = "#userId", condition = "#userId != null")
    public HistoryTopicVO saveHistoryTopic(String userId, String topic) {
        DiaryTopicDO diaryTopic = diaryTopicRepository.findByTopic(topic);
        if (diaryTopic == null) {
            DiaryTopicDO saveDiaryTopic = DiaryTopicDO.builder()
                    .userId(Long.parseLong(userId))
                    .topic(topic)
                    .build();
            diaryTopic = diaryTopicRepository.save(saveDiaryTopic);
        }
        HistoryTopicVO historyTopicVO = new HistoryTopicVO();
        copyNonNullProperties(diaryTopic, historyTopicVO);
        try {
            UserDiaryTopicHistoryDO userDiaryTopicHistory = userDiaryTopicHistoryRepository.findByUserIdAndTopicId(Long.parseLong(userId), diaryTopic.getId());
            if (userDiaryTopicHistory == null) {
                userDiaryTopicHistory = UserDiaryTopicHistoryDO.builder()
                        .userId(Long.parseLong(userId))
                        .topic(topic)
                        .topicId(diaryTopic.getId())
                        .build();
            } else if (userDiaryTopicHistory != null && userDiaryTopicHistory.getIsDelete()) {
                userDiaryTopicHistory.setIsDelete(false);
            }
            userDiaryTopicHistoryRepository.save(userDiaryTopicHistory);
        } catch (Exception e) {
            log.info("topic = {} 重复，不用重复保存！", topic);
            return historyTopicVO;
        }
        return historyTopicVO;
    }

    /**
     * 关注话题
     *
     * @param userId
     * @param topic
     */
    @CacheEvict(cacheNames = TOPIC_ATTENTION, key = "#topic", condition = "#topic != null")
    public String attentionTopic(String userId, String topic, Long topicId) {
        try {
            UserDiaryTopicAttentionDO attention = userDiaryTopicAttentionRepository.findByUserIdAndTopicAndIsAttention(Long.parseLong(userId), topic, false);
            if (attention != null) {
                attention.setIsAttention(true);
            } else {
                attention = UserDiaryTopicAttentionDO.builder()
                        .userId(Long.parseLong(userId))
                        .topic(topic)
                        .topicId(topicId)
                        .build();
            }
            userDiaryTopicAttentionRepository.save(attention);
        } catch (Exception e) {
            log.info("topic = {} 已关注，不用重复关注！", topic);
            return "已关注，不用重复关注！";
        }
        return "已关注!";
    }

    /**
     * 取消话题关注
     *
     * @param userId
     * @param topic
     */
    @CacheEvict(cacheNames = TOPIC_ATTENTION, key = "#topic", condition = "#topic != null")
    public String cancelAttention(String userId, String topic) {
        UserDiaryTopicAttentionDO userDiaryTopicAttention = userDiaryTopicAttentionRepository.findByUserIdAndTopicAndIsAttention(Long.parseLong(userId), topic, true);
        if (userDiaryTopicAttention != null) {
            userDiaryTopicAttention.setIsAttention(false);
            userDiaryTopicAttentionRepository.save(userDiaryTopicAttention);
        } else {
            return "已取消关注,不用重复取消关注！";
        }
        return "已取关！";
    }


    @Cacheable(cacheNames = TOPIC_ID, key = "#topicId", unless = "#result == null")
    public DiaryTopicDO findDiaryTopic(long topicId) {
        return diaryTopicRepository.findOne(topicId);
    }

    /**
     * 话题关注数
     *
     * @param topic
     */
    @Cacheable(cacheNames = TOPIC_ATTENTION, key = "#topic", unless = "#result == null")
    public Long countAttention(String topic) {
        Long count = userDiaryTopicAttentionRepository.countByTopicAndIsAttention(topic, true);
        return count;
    }

    public MyTopicVO topicDetail(HistoryTopicVO historyTopicVO, DiaryTopicDO diaryTopic) {
        UserDiaryTopicAttentionDO userDiaryTopicAttention = userDiaryTopicAttentionRepository.findByUserIdAndTopicAndIsAttention(historyTopicVO.getUserId(), historyTopicVO.getTopic(), true);
        MyTopicVO myTopicVO = new MyTopicVO();
        myTopicVO.setIsAttention(false);
        if (userDiaryTopicAttention != null) {
            myTopicVO.setIsAttention(true);
        }
        myTopicVO.setAttentionCount(this.countAttention(historyTopicVO.getTopic()));
        //日记数
        myTopicVO.setDiaryCount(diaryService.countByTopicId(historyTopicVO.getId()));
        //话题
        myTopicVO.setTopic(diaryTopic.getTopic());
        myTopicVO.setTopicId(historyTopicVO.getId());
        return myTopicVO;
    }

    /**
     * 关注的话题列表
     *
     * @param userId
     */
    public Page<MyTopicVO> attentionaTopicList(long userId, int page, int pageSize) {
        Pageable pageable = new PageRequest(page - 1, pageSize);
        org.springframework.data.domain.Page userDiaryTopicAttentionsPage = userDiaryTopicAttentionRepository.findAllByUserIdAndIsAttentionOrderByUpdateTimeDesc(userId, true, pageable);
        List<UserDiaryTopicAttentionDO> userDiaryTopicAttentions = userDiaryTopicAttentionsPage.getContent();

        List<MyTopicVO> myTopicVOList = new ArrayList<>();
        for (UserDiaryTopicAttentionDO userDiaryTopicAttention : userDiaryTopicAttentions) {
            MyTopicVO myTopicVO = new MyTopicVO();
            copyNonNullProperties(userDiaryTopicAttention, myTopicVO);
            myTopicVO.setAttentionCount(this.countAttention(userDiaryTopicAttention.getTopic()));
            //日记数
            myTopicVO.setDiaryCount(diaryService.countByTopicId(userDiaryTopicAttention.getTopicId()));
            myTopicVOList.add(myTopicVO);
        }

        Page<MyTopicVO> result = new Page<>();
        result.setRows(myTopicVOList);
        result.setTotal(userDiaryTopicAttentionsPage.getTotalElements());

        return result;
    }

    @CacheEvict(cacheNames = TOPIC_HISTORY, key = "#userId", condition = "#userId != null")
    public void deleteHistoryTopic(String userId) {
        List<UserDiaryTopicHistoryDO> userDiaryTopicHistoryList = userDiaryTopicHistoryRepository.findByUserIdAndIsDeleteOrderByUpdateTimeDesc(Long.parseLong(userId), false);
        userDiaryTopicHistoryList.stream().peek(userDiaryTopicHistory -> userDiaryTopicHistory.setIsDelete(true))
                .collect(Collectors.toList());
        userDiaryTopicHistoryRepository.save(userDiaryTopicHistoryList);
    }
}
